//
//  QSTabTitleView.swift
//  TestSwift
//
//  Created by Song on 2019/2/25.
//  Copyright © 2019 Song. All rights reserved.
//

import UIKit

/// 代理
protocol QSTabTitleViewDelegate: class {
    /// 切换标题
    ///
    /// - Parameters:
    ///   - titleView: titleView
    ///   - startIndex: 切换前标题索引
    ///   - endIndex: 切换后标题索引
    func qs_tabTitleView(titleView: QSTabTitleView, startIndex: Int, endIndex: Int)
}

class QSTabTitleView: UIView {
    // MARK: - Propertys
    /// 代理
    weak var qs_delegate: QSTabTitleViewDelegate?
    
    private var titleBtnArr: Array<UIButton> = Array<UIButton>.init()
    
    /// 标题数组
    var titleArray: Array<String> = Array<String>.init() {
        didSet {
            // 删除原来的子控件
            for btn in titleBtnArr {
                btn.removeFromSuperview()
            }
            
            // 添加子控件
            for i in 0 ..< titleArray.count {
                let btn = UIButton.init()
                self.scrollView.addSubview(btn)
                btn.tag = i + 666
                btn.setTitle(titleArray[i], for: .normal)
                btn.setTitle(titleArray[i], for: .disabled)
                btn.addTarget(self, action: #selector(clickTitleBtn(_:)), for: .touchUpInside)
                
                self.titleBtnArr.append(btn)
            }
        }
    }
    
    /// 最左边按钮距离左边的距离
    var leftTitleMargin: CGFloat = 20.0 {
        didSet {
            self.setNeedsLayout()
            self.scrollView.layoutIfNeeded()
        }
    }
    
    /// 最右边按钮距离右边边的距离
    var rightTitleMargin: CGFloat = 20.0 {
        didSet {
            self.setNeedsLayout()
            self.scrollView.layoutIfNeeded()
        }
    }
    
    /// 标题文字间距，默认20.0
    var titleMargin: CGFloat = 20.0 {
        didSet {
            self.setNeedsLayout()
            self.scrollView.layoutIfNeeded()
        }
    }
    
    /// 标题字体大小，默认15.0
    var titleFont: UIFont = UIFont.systemFont(ofSize: 15.0) {
        didSet {
            if selectTitleFont == nil {
                selectTitleFont = titleFont
            }
            
            for btn in self.titleBtnArr {
                btn.titleLabel?.font = titleFont
            }
            self.setNeedsLayout()
            self.scrollView.layoutIfNeeded()
        }
    }
    
    /// 标题选中字体大小，默认与titleFont一致
    var selectTitleFont: UIFont?
    
    /// 标题正常颜色，默认black
    var normalTitleColor: UIColor = .black {
        didSet {
            for btn in titleBtnArr {
                btn.setTitleColor(normalTitleColor, for: .normal)
            }
        }
    }
    
    /// 标题选中颜色，默认red
    var selectTitleColor: UIColor = .red {
        didSet {
            for btn in titleBtnArr {
                btn.setTitleColor(selectTitleColor, for: .disabled)
            }
        }
    }
    
    /// 指示器颜色，默认与titleSelectColor一样
    var indicatorColor: UIColor? {
        didSet {
            self.indicatorView.backgroundColor = indicatorColor
        }
    }
    /// 指示器宽
    var indicatorWidth: CGFloat = 0.0
    /// 指示器高，默认2.0
    var indicatorHeight: CGFloat = 2.0 {
        didSet {
            self.indicatorView.layer.cornerRadius = indicatorHeight / 2.0
            self.indicatorView.layer.masksToBounds = true
        }
    }
    
    /// 当前选中标题索引，初始化后要手动设置
    var selectIndex: UInt = 10000 {
        didSet {
            if selectIndex < 0 || selectIndex > titleBtnArr.count || oldValue == selectIndex {
                return
            }
            
            let index = oldValue == 10000 ? 0 : oldValue
            let oldBtn = self.titleBtnArr[Int(index)]
            oldBtn.isEnabled = true
            
            self.clickTitleBtn(self.titleBtnArr[(Int)(selectIndex)])
            // 执行代理方法
            guard let _ = self.qs_delegate?.qs_tabTitleView(titleView: self, startIndex: Int(oldValue), endIndex: Int(selectIndex)) else { return }
        }
    }
    
    /// 底部分割线颜色，默认透明
    var bottomLineColor: UIColor = .clear {
        didSet {
            self.lineView.backgroundColor = bottomLineColor
        }
    }
    
    /// 背景颜色，默认白色
    var bgColor: UIColor = .white {
        didSet {
            self.scrollView.backgroundColor = bgColor
        }
    }
    
    // MARK: - 初始化
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        // 添加子控件
        self.setupSubViews()
    }
    
    convenience init(titleArray: Array<String>) {
        self.init(frame: .zero)
        self.setValue(titleArray, forKey: "qs_titleArray")
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 使用kvc，undefine方法
    override func setValue(_ value: Any?, forUndefinedKey key: String) {
        if key == "qs_titleArray" { // 设置titleArray
            guard let newValue = value as? Array<String> else {
                return
            }
            
            titleArray = newValue
        }
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        // 计算所有title的宽度
        var totalWidth: CGFloat = 0.0
        for title in titleArray {
            let width = self.obtainTextWidth(text: title, font: titleFont)
            totalWidth += width
        }
        totalWidth += (titleMargin * (CGFloat)(titleArray.count + 1))
        
        // 对按钮进行布局
        var lastBtn = UIButton.init()
        for i in 0 ..< titleBtnArr.count {
            let btn = titleBtnArr[i]
            btn.snp.remakeConstraints { (make) in
                if i == 0 {
                    make.left.equalTo(leftTitleMargin)
                } else {
                    make.left.equalTo(lastBtn.snp.right).offset(titleMargin)
                }
                make.top.bottom.equalTo(0.0)
                make.height.equalTo(self.frame.size.height - 1.0)
                if i == (titleBtnArr.count - 1) {
                    make.right.equalTo(-rightTitleMargin)
                }
                
                if totalWidth < self.frame.size.width {
                    let width = self.obtainTextWidth(text: titleArray[i], font: titleFont) + ((self.frame.size.width - totalWidth) / (CGFloat)(titleArray.count))
                    make.width.equalTo(width)
                } else {
                    let width = self.obtainTextWidth(text: titleArray[i], font: titleFont)
                    make.width.equalTo(width + 1.5)
                }
            }
            
            btn.setTitleColor(normalTitleColor, for: .normal)
            btn.setTitleColor(selectTitleColor, for: .disabled)
            btn.titleLabel?.font = titleFont
            
            lastBtn = btn
        }
    }
    
    // MARK: - Event Response
    @objc private func clickTitleBtn(_ btn: UIButton) {
        let oldBtn = self.titleBtnArr[(Int)(self.selectIndex)]
        oldBtn.isEnabled = true
        
        btn.isEnabled = false
        self.selectIndex = UInt(btn.tag - 666)
        self.moveIndicatorView()
    }
    
    // MARK: - Private Methods
    func setupSubViews() {
        self.backgroundColor = .white
        
        self.addSubview(self.lineView)
        self.lineView.snp.makeConstraints { (make) in
            make.left.right.bottom.equalTo(0.0)
            make.height.equalTo(1.0)
        }
        
        self.addSubview(self.scrollView)
        self.scrollView.snp.makeConstraints { (make) in
            make.top.left.right.equalTo(0.0)
            make.bottom.equalTo(self.lineView.snp.top).offset(0.0)
            make.height.equalTo(self.frame.height - 1.0)
            make.width.equalTo(self.frame.width)
        }
        
        self.scrollView.addSubview(self.indicatorView)
    }
    
    /// 移动指示器
    ///
    /// - Parameter animated: 动画
    private func moveIndicatorView(animated: Bool = true) {
        self.indicatorView.superview?.layoutIfNeeded()
        UIView.animate(withDuration: 0.35, animations: {
            self.indicatorView.snp.remakeConstraints { (make) in
                let btn = self.titleBtnArr[(Int)(self.selectIndex)]
                make.centerX.equalTo(btn)
                make.height.equalTo(self.indicatorHeight)
                make.bottom.equalTo(0.0)
                if self.indicatorWidth > 0 {
                    make.width.equalTo(self.indicatorWidth)
                } else {
                    let width = self.obtainTextWidth(text: btn.titleLabel?.text ?? "", font: self.selectTitleFont ?? self.titleFont)
                    make.width.equalTo(width)
                }
            }
            
            self.indicatorView.superview?.layoutIfNeeded()
        }) { (finished) in
            self.scrollSelectBtnToCenter()
        }
    }
    
    /// 把选中按钮移动到中间
    ///
    /// - Parameter animated: 动画
    private func scrollSelectBtnToCenter(animated: Bool = true) {
        let selectBtn = self.titleBtnArr[(Int)(self.selectIndex)]
        let centerRect = CGRect.init(x: selectBtn.center.x - self.scrollView.frame.width / 2.0, y: 0, width: self.scrollView.frame.width, height: self.scrollView.frame.height)
        self.scrollView.scrollRectToVisible(centerRect, animated: animated)
    }
    
    // MARK: - 控件
    private lazy var scrollView: UIScrollView = {
        let scrV = UIScrollView.init()
        scrV.showsVerticalScrollIndicator = false
        scrV.showsHorizontalScrollIndicator = false
        return scrV
    }()
    
    private lazy var lineView: UIView = {
        let view = UIView.init()
        view.backgroundColor = bottomLineColor
        return view
    }()
    
    private lazy var indicatorView: UIView = {
        let view = UIView.init()
        view.backgroundColor = indicatorColor ?? selectTitleColor
        return view
    }()
}

extension QSTabTitleView {
    /// 获取字符串文字的宽度
    ///
    /// - Parameters:
    ///   - font: 字体大小
    ///   - height: 高度，默认为20.0
    /// - Returns: 宽度
    fileprivate func obtainTextWidth(text: String, font : UIFont, height : CGFloat = 20.0) -> CGFloat {
        let attributes = [NSAttributedString.Key.font:font] // 设置字体大小
        let option = NSStringDrawingOptions.usesLineFragmentOrigin
        
        let rect : CGRect = text.boundingRect(with: CGSize.init(width: CGFloat.greatestFiniteMagnitude, height: height), options: option, attributes: attributes, context: nil)
        
        return rect.width
    }
}
